/*
    PhotoFlip, a free 3d photo managment suite.
    Copyright (C) 2007  Elisée MAURER, Gaétan WALTER
    
    This file is part of PhotoFlip.
    Contact: http://www.photoflip.org/

    PhotoFlip is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    PhotoFlip is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PhotoFlip.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef LIBRARY_HPP_INCLUDED
#define LIBRARY_HPP_INCLUDED

#include "constants.hpp"
#include <GL/gl.h>

#include <glibmm.h>

#include <cairomm/surface.h>
#include <cairomm/context.h>

#include <string>
#include <vector>

//! simple %photo struct
/*!
  Stores information for one photo
*/
struct photo {
	photo(std::string filename);
	
	std::string filename;
	bool hasTexture, hasFrame;
	GLuint texPhoto, texFrame;
	bool selected;
};

//! photo %collection class
/*!
  It maps a simple directory containing image files (here named photos).
*/
class collection {
	private:
		std::string m_name;
		std::vector<photo> m_photos;
		
		// photo case (for desktop visualisation)
		int m_caseOpening;
		Cairo::RefPtr<Cairo::ImageSurface> m_caseLabelSurface;
		Cairo::RefPtr<Cairo::Context> m_caseLabelContext;
		GLuint m_texCaseLabel;
		
		bool m_hasThumbnail;
		GLuint m_texThumbnail;
	public:
		collection();
		~collection();
		
		const std::string& getName() { return m_name; }
		void setName(std::string name);
		
		bool hasThumbnail() { return m_hasThumbnail; }
		GLuint getThumbnailTexture() { return m_texThumbnail; }
		void setThumbnailTexture(GLuint texture);
		
		void setCaseOpening(int opening);
		inline int getCaseOpening() { return m_caseOpening; }
		
		void prepareCaseLabel(int height);
		void renderCaseLabel();
		
		std::vector<photo>& getPhotos() { return m_photos; }
};

//! The photo %library, which keeps track of all the user's collections
/*!
  The library provides interface to the "library/" directory. It also ships
  with the desktop visualisation, which allow the user to select a collection
  to browse.
*/
class library {
	private:
		bool m_wasInit;
		
		// collections
		std::vector<photo> m_basket;
		std::vector<collection> m_collections;
		int m_currentCollection;
		
		// desktop
		GLuint m_texError;
		GLuint m_texCase[5];
		
		int m_element;
		float m_angle;
		int m_spin;

		// multi-threading
		//Glib::/*Rec*/Mutex mutexCollections;
	public:
		//! Library constructor, parses library directory tree.
		library();
		//! Library destructor.
		~library();
		
		void setErrorTexture(GLuint texture);
		//! Returns texture to use when no other is available.
		GLuint getErrorTexture() { return m_texError; }
		
		// collection managment
		//! Threaded function to generate photo thumbnails at program start.
		void createThumbnails();
		//! Returns unsorted photos / basket
		std::vector<photo>& getBasket() { return m_basket; }
		
		//! Returns collections vector.
		std::vector<collection>& getCollections() { return m_collections; }
		//! Sets currently browsed collection.
		void setCollection(int collection);
		//! Returns current collection number
		int getCollection();
		
		//! Returns whether we are currently browsing a collection.
		bool inCollection() { return (m_currentCollection >= 0); }
		//! Returns current collection name.
		std::string getCollectionName();
		//! Returns current collection's photos vector.
		std::vector<photo>& getCollectionPhotos();
		
		// desktop
		//! Sets current element in visualisation (photo) or desktop (collection).
		void setElement(int element);
		//! Gets current element.
		int getElement() { return m_element; }
		
		//! Renders a small photo to be placed in a photo case for quick preview.
		void renderThumbnail(GLuint texture);
		//! Renders a photo case representing a collection.
		void renderCase(int open);
		
		//! Updates internal sizes
		void setSize(int width, int height);
		//! Initializes desktop scene.
		void initScene();
		//! Updates desktop scene.
		bool updateScene();
		//! Renders desktop scene (collection selection screen).
		void renderScene(/*int width, int height*/);
		//! Renders desktop overlay (collection names).
		void renderOverlay(int width, int height);
};

#endif // LIBRARY_HPP_INCLUDED
